home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
graphics
/
mfpic
/
alfatest
/
mf-revu.tex
< prev
next >
Wrap
Text File
|
1994-07-20
|
12KB
|
326 lines
%%%
%%% File: mf-revu.tex
%%%
%%% mfpic 0.2.9 alpha Tue 21 July 1994
%%%
\magnification=\magstep1
% heading macros
\newskip\myskip\myskip=10pt plus 1pt
\def\doskip{\vskip\myskip}
\long\def\head#1{\doskip\noindent $\bullet$ {\it #1} \par\doskip\nobreak}
\long\def\subhead#1{\doskip {\sl #1} \par\doskip\nobreak}
% abbreviations
\def\LaTeX{{\rm L\raise.42ex\hbox{\kern-.3em a}\kern-.15em\TeX}}
\font\manual=logo10 % may want to use manfnt here instead
\def\MF{{\manual META}\-{\manual FONT}}
\def\PS{{\rm Post}\-{\rm Script}}
\def\texmacro#1{{\tt\char\escapechar #1}}
% verbatim text -- extracted from The TeXbook, pages 380--381.
\def\verbatim{\tt
\def\par{\leavevmode\endgraf}
\obeylines \obeyspaces}
{\obeyspaces\global\let =\ }
\centerline{\bf A Review of \MF{} Programming}
\centerline{Geoffrey Tobin ({\tt G.Tobin@ee.latrobe.edu.au}) 21 July 1994}
The best reference for \MF{} programming is undoubtedly Professor
Donald E.~Knuth's {\it The \MF{}book}, first published by
Addison-Wesley and copyrighted by the American Mathematical Society
in 1986, ISBN 0-201-13445-4.
However, this document provides reminders some facets of \MF{}.
\head{Types}
\MF{} has nine ($9$) types of expression: {\tt boolean}, {\tt numeric},
{\tt pair}, {\tt path}, {\tt pen}, {\tt picture}, {\tt string},
{\tt transform}, and {\it vacuous}. The first eight ($8$) are
{\it named} types; their names can be used to declare variables (for
example, {\tt string surname;}), or to test the type of a variable or
expression (as in {\tt message "x is " \& if pair x: "indeed" else:
"not" fi \& " a pair";}). Every undeclared \MF{} variable is
{\tt numeric}.
Statements can be treated as expressions of the {\it vacuous} type.
Expressions of {\tt boolean} type are either {\tt true} or {\tt false},
whereas {\it vacuous} expressions have only one possible value.
The allowed values of all the types, and the range of expressions
available in \MF{}, are described in {\it The \MF{}book}.
\head{Groups}
A {\it group} is an {\it compound} expression of the form
{\tt begingroup A; B; C; D endgroup} which may contain several
statements; its value is that of its last expression, so
{\tt begingroup message "hello"; 123.45 endgroup}
has the value of $123.45$, which is {\tt numeric}.
If the group is empty, or if its last item is a semicolon,
then the group has the {\it vacuous} type.
\head{Macros}
{\it Macros} are the \MF{} equivalent of functions and procedures.
There are two broad classes of macro: untyped ({\tt def}) and typed
({\tt vardef}). Typed macros are permitted to have the {\it vacuous}
type: an example is {\tt vardef fred = message "I am called Fred";
enddef;}\ . In fact, {\tt vardef A = B enddef;} is effectively a
shorthand for {\tt def A = begingroup B endgroup enddef;}\ .
\head{Numerics}
\subhead{\MF{} Numeric Operations}
The arithmetic operators {\tt +}, {\tt -}, {\tt *}, {\tt /} are
primitives in \MF{}. So are Pythagorean addition ({\tt ++}) and
subtraction ({\tt +-+}): $x ++ y = \sqrt {x^2 + y^2}$ and
$x +-+ y = \sqrt {x^2 - y^2}$.
Plain \MF{} defines exponentiation ({\tt **}), remainder ({\tt mod})
and integer division ({\tt div}).
\subhead{\MF{} Numeric Relations}
Numeric expressions can be compared: relations include equality,
({\tt =}), and inequalities ({\tt <>}, {\tt >}, {\tt <}, {\tt >=},
{\tt <=}).
\subhead{\MF{} Numeric Functions}
\MF{} has some useful {\tt numeric} functions built-in. These
include: length, sqrt, sind, cosd, mlog, mexp, floor, angle,
uniformdeviate, normaldeviate.
{\bf length $x$} is the absolute value of $x$.
{\bf sqrt $x$} is the square root of $x$.
{\bf sind $x$} is the sine of $x$ degrees.
{\bf cosd $x$} is the cosine of $x$ degrees.
{\bf angle $(x, y)$} is the arctangent of $y/x$.
{\bf mlog $x$} is $256 \hbox{\tt ln} x$, where {\tt ln} is the
logarithm to the base $e$.
{\bf mexp $x$} is $e^{x/256}$.
{\bf floor $x$} is the largest integer less than or equal to $x$.
{\bf uniformdeviate $x$} is a uniformly distributed random number
between $0$ and $x$.
{\bf normaldeviate} is a normally distributed random number with mean
$0$ and standard deviation $1$.
The random number generators can be restarted at a given stage by
assigning a {\tt numeric} value to the primitive internal variable
{\bf randomseed}.
Plain \MF{} defines {\bf ceiling}, {\bf abs} (same as {\bf length}),
{\bf round}, {\bf min} and {\bf max}, among other functions.
\head{Pairs}
Subsequently, we often speak of {\it points} in the graphical sense.
These are represented in \MF{} by values of type {\tt pair}.
Constants of type {\tt pair} have the form $(x, y)$,
where $x$ and $y$ are both {\tt numeric} constants.
A variable $p$ of type {\tt pair} is equal to the
{\tt pair} expression ({\tt xpart} $p$, {\tt ypart} $p$).
\head{Paths}
A {\tt path} represents a type of continuous curve called a
{\bf B\'ezier}, which is comprised of a chain of {\bf segments}.
Each segment has a shape determined by four {\bf control points}.
Two of the control points, the {\it key} points, are the segment's
endpoints; often we let \MF{} determine the other two, as in the
{\tt path} expression $p_1..p_2..p_3$, which has two segments,
from $p_1$ to $p_2$, and from $p_2$ to $p_3$.
\head{Pens}
Pens are a distinctive feature of \MF{}, whereby quite refined
figures can be drawn. Pens are filled convex shapes that
are moved along {\tt path}s, to alter {\tt picture} pixel values in
often complicated ways.
Two pens are initially present in MF{}, {\tt nullpen} and
{\tt pencircle}. Since {\tt nullpen} is the single point $(0,0)$,
which contains no pixels, it cannot be seen, so it can be used
for filling a region without fuzzing its boundary. By contrast,
{\tt pencircle} is circular, with the points $(\pm0.5, 0)$ and
$(0, \pm0.5)$ on its circumference.
Other pens are constructed as convex polygons via {\tt makepen $c$},
where $c$ is a closed {\tt path}; they key points of $c$ become the
vertices of the pen.
Now, {\tt pencircle} and {\tt makepen $c$} are called {\it future}
pens. They are continuous, whereas pictures are discrete, so pens,
like pairs and paths, must be {\it rendered} discrete before being
applied to a picture.
By contrast, {\tt nullpen}, all {\tt pen} variables, and any
pen expression in parentheses, are already {\it discrete} pens.
{\it Future} pens can be transformed by scaling, translating, and so
on, just as pairs and paths can; but {\it discrete} pens cannot.
An example of an elliptical future pen is {\tt pencircle xscaled 30
yscaled 20}, the discrete pen for which is illustrated on page 148 of
{\it The \MF{}book}.
\head{Pictures}
\MF {\tt picture}s contain pixels arranged as a regular grid of
squares. One of the pixels has as its boundary the {\it unit square},
which is the {\tt path} $(0,0)--(0,1)--(1,1)-(1,0)$. Pictures are
built up from the {\tt nullpicture}, which has all pixels zero ($0$),
using {\tt addto}, and their pixels are trimmed using {\tt cull}.
Picture variables can be assigned: $v := W;$ where $v$ is a
{\tt picture} variable, and $W$ is a {\tt picture} expression
such as $u + w$, $u - w$, $+u$, $-u$, or combinations of these.
Picture $v$ can have picture $w$ added to it by
{\tt addto $v$ also $w$}, which {\it The MF{}book, page 118} explains
is faster and uses less memory than {\tt $v := v + w$} but is
otherwise the same.
The meaning of $v + w$, for example, is a picture in which each pixel
is the sum of the two pixels that occupy the same position in pictures
$v$ and $w$ respectively. The effects on pixel values of filling and
drawing are much less predictable, and depend greatly on which
{\tt pen} is used.
Filling a {\it closed} path $c$ in a picture $v$ uses
{\tt addto $v$ contour $c$ {\it <with list>}},
Drawing the outline of a path $f$ uses
{\tt addto $v$ doublepath $c$ {\it <with list>}}.
A {\it <with list>} can be empty, or it can be one or both of the
phrases {\tt withpen {\it <pen expression>}}
and {\tt withweight {\it <numeric expression>}}.
By choosing different pens, drawing is refined, as in calligraphy.
Weights are weighting factors for pixels.
To change all pixels in {\tt picture} variable $v$ that have values
between $2$ and $4$ (inclusive) into $-5$, and all other pixels to
zero, use:
{\tt cull $v$ keeping $(2,4)$ withweight $-5$}.
To zero all pixels with values between $-3$ and $1$ (inclusive),
and to change all other pixels into $2$, use:
{\tt cull $v$ dropping $(-3,1)$ withweight $2$},
If the {\tt withweight} phrase is omitted, then the surviving
pixels have value one ($1$).
{\it Beware} of attempting to change zero-valued pixels to nonzero,
as zero-valued pixels extend to infinity in all directions.
\head{Transforms}
Affine transforms are the natural transformations of Euclidean
geometry: the linear transformations augmented by translation.
In two dimensions, transforms are completely specified by their
action on three non-collinear points in the plane. If $T$ is
a {\tt transform}, and $p$ is a pair, then $T$ maps $p$ onto this
{\tt pair}: $p$ {\tt transformed} $T$. Thus \MF{} can construct
any affine transform: for example, plain \MF{} defines the
{\bf identity} transform. Plain \MF{} also defines a macro named
{\bf inverse} such that
{\bf inverse $T$ transformed $T$ $=$ identity}.
Each transform $T$ has six components, and can be expressed as a
linear transformation followed by a translation. The translation
components of $T$ are {\tt xpart $T$} and {\tt ypart $T$}, and
the four linear components are {\tt xxpart $T$}, {\tt xypart $T$},
{\tt yxpart $T$} and {\tt yypart $T$}. Employing the obvious
notation, $T$ is applied as:
$$
\left(
\matrix{t_x \cr t_y}
\left|
\vphantom{\matrix{t_xy \cr t_yy}}
\right.
\matrix{ t_{xx} & t_{yx} \cr t_{xy} & t_{yy}}
\right)
\pmatrix{x \cr y}
=
\pmatrix{t_x + t_{xx} x + t_{xy} y \cr
t_y + t_{yx} x + t_{yy} y}
$$
\MF{} also provides seven primitive transforms, listed on page
141 of {\it The \MF{}book}:
\halign
{\indent#\hfil&\quad#\hfil\cr
$(x,y)$ {\tt shifted} $(a,b)$ & $ = (x+a, y+b) $ \cr
$(x,y)$ {\tt scaled} $s$ & $ = s (x, y) $ \cr
$(x,y)$ {\tt xscaled} $s$ & $ = (sx, y) $ \cr
$(x,y)$ {\tt yscaled} $s$ & $ = (x, sy) $ \cr
$(x,y)$ {\tt slanted} $s$ & $ = (x,y) + s (y, 0) $ \cr
$(x,y)$ {\tt rotated} $\theta$ & $ = (x \cos \theta - y \sin \theta,
x \sin \theta + y \cos \theta) $ \cr
$(x,y)$ {\tt zscaled} $(a,b)$ & $ = (xu - yv, xv + yu) $ \cr
}
These operations are taught in secondary school mathematics;
for example, {\tt slanted} is skewing parallel to the X axis.
Interpreting a pair as a complex number in Cartesian coordinates,
{\tt zscaled} is complex multiplication.
\head{Composite Variables}
\MF{} allows {\it composite} variables --- homogeneous {\it arrays},
heterogeneous {\it suffixes}, and arbitrary combinations of those.
One can declare composite variables, and test whether they
{\it contain} a given structure. However, these are not fully-fledged
types, since every expression has one of the nine {\it simple} types.
For example, after declaring {\tt path p[];} of what type is {\tt p} ?
It's {\tt numeric}!
Moreover, \MF{} {\it lacks} pointers. It is not possible for a macro
to return a value that has not one of the nine {\it simple} types.
The allowed syntax {\tt vardef b[] = $\cdots$ enddef;} may suggest
that this macro returns an array, but in fact {\tt b[3]} {\it expands}
to the whole {\it replacement text} of the macro.
Here is a macro that is useful for testing the type of a variable,
suffix or expression:
{
\verbatim
def type suffix x =
message str x \& " is "
\&
if known x: "a known "
else: "an unknown "
fi
\&
if boolean x: "boolean"
elseif numeric x: "numeric"
elseif pair x: "pair"
elseif path x: "path"
elseif pen x: "pen"
elseif picture x: "picture"
elseif string x: "string"
elseif transform x: "transform"
else: "vacuous"
fi;
enddef;
}
\end
%%%
%%% end mf-revu.tex
%%%